#include <iostream>
#include <pthread.h>
#include <string>
#include <cstring>
//线程接口封装


class Thread
{
    enum status
    {
        RUNNING=0, //运行
        ERROR,     //异常
        EXITED     //退出
    };
    typedef void* (*FUNC)(void*);
public:
    Thread() {};
    Thread(const std::string& name,FUNC f,void* a)
        :_name(name)
        ,_tid(-1)
        ,_status(EXITED)
        ,_func(f)
        ,_args(a)
        ,_detach(0)
        {}

    
    void* operator()()
    {
        return _func(_args);
    }

    static void* runHelper(void* args)
    {
        Thread* t = static_cast<Thread*>(args);
        return (*t)();
    }

    void run()
    {
        int n = pthread_create(&_tid,nullptr,runHelper,this);
        if(n != 0)
        {
            std::cerr<<"create thread error! "<<"  ERROR:"<<n<<"  "<<strerror(n)<<std::endl;
            exit(-1);
        }
        _status = RUNNING;
    }

    void* join()
    {
        if(!_detach && _status == RUNNING) //_detach为1则非分离状态
        {
            void* ret = nullptr;
            int n = pthread_join(_tid,&ret);
            if(n!=0)
            {
                std::cerr<<"join thread error! "<<"  ERROR:"<<n<<"  "<<strerror(n)<<std::endl;
                exit(-1);
            }
            return ret;
        }
        std::cout<<"线程已分离或未启动,等待失败!"<<std::endl;
        return nullptr;
    }

    void cancle() //终止自己
    {
        int n = pthread_cancel(_tid);
        if(n!=0)
        {
            std::cerr<<"cancle thread error! "<<"  ERROR:"<<n<<"  "<<strerror(n)<<std::endl;
            exit(-1);
        }
    }

    void detach()
    {
        int n = pthread_detach(_tid);
        if(n!=0)
        {
            std::cerr<<"detach thread error! "<<"  ERROR:"<<n<<"  "<<strerror(n)<<std::endl;
            exit(-1);
        }
        _detach = 1;
    }

    pthread_t gettid()
    {
        if(_tid == -1)
        {
            std::cout<<"线程还未创建！"<<std::endl;
            return 0;
        }
        return _tid;
    }

    int getstatus()
    {
        return _status;
    }

    std::string getname()
    {
        return _name;
    }

private:
    
    std::string _name; //线程名
    pthread_t _tid; //线程id
    status _status; //线程状态
    FUNC _func; //执行函数
    void* _args; //执行函数参数
    int _detach; //分离状态
};